import { Injectable } from '../decorators/inject';
import { TableDatas } from './table-datas';
import { Config } from './config';
import { Inject } from '../decorators/inject';
import { NExcel } from '../types';
import { MergeCell } from './merge-cell';
import { ICellFillControl, ICellBaseControl } from '../types/common.interface';
import { NFill } from '../types/style.interface';
import { Cache } from './cache';
@Injectable('FillRender')
export class FillRender {
    protected widths: Map<number, number> = new Map();
    protected heights: Map<number, number> = new Map();
    protected startPosition: CellPosition = {row: 0, col: 0};
    protected endPosition: CellPosition = {row: 0, col: 0};
    protected fillCtx: CanvasRenderingContext2D;
    protected fillValues: {start: TCoord,  size: TSize, color: string}[] = [];
    constructor(
        protected conf: Config,
        protected tableData: TableDatas,
        protected mergeCell: MergeCell,
        @Inject(NExcel.TableDataCanvasFillToken) protected canvasDataFillEle: HTMLCanvasElement,
        protected cache: Cache
    ) {

    }
    public init() {
        this.fillCtx = this.canvasDataFillEle.getContext('2d');
    }
    public addFill(start: TCoord, size: TSize, color: string) {
        this.fillValues.push({start, size, color});
    }
    protected isWrithColor(color: string) {
        if(color === '#FFFFFF') {
            return true;
        }
        return false;
    }
    protected drawFill(start: TCoord, size: TSize, color: string) {
        this.fillCtx.save();
        this.fillCtx.beginPath();
        this.fillCtx.fillStyle = color;
        let x = start.x;
        let y = start.y;
        let w = size.w;
        let h = size.h;
        if(this.isWrithColor(color)) {
            this.fillCtx.fillRect(x, y, w, h);
            // this.fillCtx.fillRect(x + this.conf.pixelRatio, y + this.conf.pixelRatio + 1, w - 2*this.conf.pixelRatio, h - 2*this.conf.pixelRatio);
        } else {
            this.fillCtx.fillRect(x, y, w, h);
        }
        this.fillCtx.restore();
    }
    protected renderCellFill() {
        for(let item of this.fillValues) {
            this.drawFill(item.start, item.size, item.color);
        }
        this.fillValues = [];
    }
    protected renderFullRow(start: number, end: number, fill: NFill.IFill) {
        let tableSize = this.conf.getTableSize();
        let startX = this.conf.header.row.width;
        let width = tableSize.width - startX;
        for(let row = start; row <= end; row++) {
            if(row > this.cache.rowBoundary.end) break;
            if(this.conf.freeze.row === -1) {
                if(row < this.cache.rowBoundary.start) continue;
            } else {
                if(row > this.conf.freeze.row && row < this.cache.rowBoundary.start) continue;
            }
            try {
                let [startY, endY] = this.cache.getRowPositon(row);
                if(this.conf.freeze.row === -1) {
                    this.draw(startX, startY, width, endY - startY, fill.background.color);
                } else {
                    if(row <= this.conf.freeze.row) {
                        this.draw(startX, startY, width, endY - startY, fill.background.color);
                    } else {
                        if(row >= this.conf.visibleBoundary.row && row <= this.conf.visibleBoundary.endRow) {
                            this.draw(startX, startY, width, endY - startY, fill.background.color);
                        }
                    }
                }
            } catch (error) {
                console.log(error);
            }
        }
    }
    protected renderFullCol(start: number, end: number, fill: NFill.IFill) {
        let tableSize = this.conf.getTableSize();
        let startY = this.conf.header.col.height;
        let height = tableSize.height - startY;
        for(let col = start; col <= end; col++) {
            try {
                let [startX, endX] = this.cache.getColPosition(col);
                this.draw(startX, startY, endX - startX, height, fill.background.color);
            } catch (error) {
                console.log(error);
            }
        }
    }
    protected draw(x: number, y: number, w: number, h: number, color: string) {
        this.fillCtx.save();
        this.fillCtx.beginPath();
        this.fillCtx.fillStyle = color;
        this.fillCtx.fillRect(x, y, w, h);
        this.fillCtx.restore();
    }
    protected renderFullRowColFill() {
        let controlls = this.conf.cellControls as (ICellFillControl&ICellBaseControl)[];
        for(let item of controlls) {
            if(!item.fill) {
                continue;
            }
            if(item.type === 'row') {
                this.renderFullRow(item.position, item.position + item.span - 1, item.fill);
            }
            if(item.type === 'col') {
                this.renderFullCol(item.position, item.position + item.span - 1, item.fill);
            }
        }
    }
    public render() {
        this.renderFullRowColFill();
        this.renderCellFill();
    }
}